import cfg
import pygame
import time
import tool
import numpy as np
import math

'''
鼠标准星Star
'''
class Star(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.STAR_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.STAR_IMG_SIZE)
        self.rect = self.image.get_rect()
        self.rect.x,self.rect.y = 0,0
    def set_position(self,position):
        #self.rect.x,self.rect.y = position[0]-cfg.STAR_IMG_SIZE[0]/2,position[1]-cfg.STAR_IMG_SIZE[1]/2
        self.rect.centerx,self.rect.centery = position[0],position[1]
    def draw(self,screen):
        screen.blit(self.image,self.rect)

'''
英雄
'''
class Hero(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.HERO_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.HERO_IMG_SIZE)
        self.rect = self.image.get_rect()
        self.coord = [0.0,0.0]
        self.pressed=[0,0,0,0]
        self.hp = cfg.HERO_HP
        
    def set_position(self,position):
        self.rect.centerx,self.rect.centery = position[0],position[1]
        self.coord = [position[0]*1.0,position[1]*1.0]
    # 按下移动键
    def press(self,key):
        if key == pygame.K_UP or key == pygame.K_w:
            self.pressed[0] = 1
        if key == pygame.K_DOWN or key == pygame.K_s:
            self.pressed[1] = 1
        if key == pygame.K_LEFT or key == pygame.K_a:
            self.pressed[2] = 1
        if key == pygame.K_RIGHT or key == pygame.K_d:
            self.pressed[3] = 1
    # 松开移动键
    def release(self,key):
        if key == pygame.K_UP or key == pygame.K_w:
            self.pressed[0] = 0
        if key == pygame.K_DOWN or key == pygame.K_s:
            self.pressed[1] = 0
        if key == pygame.K_LEFT or key == pygame.K_a:
            self.pressed[2] = 0
        if key == pygame.K_RIGHT or key == pygame.K_d:
            self.pressed[3] = 0
    def move(self):
        if self.pressed[0]:
            self.coord[1] -= cfg.HERO_SPEED
            if self.coord[1] < 0:
                self.coord[1] = 0
            self.rect.centery = int(self.coord[1])
        if self.pressed[1]:
            self.coord[1] += cfg.HERO_SPEED
            if self.coord[1] > cfg.SCREEN_SIZE[1]:
                self.coord[1] = cfg.SCREEN_SIZE[1]
            self.rect.centery = int(self.coord[1])
        if self.pressed[2]:
            self.coord[0] -= cfg.HERO_SPEED
            if self.coord[0] < 0:
                self.coord[0] = 0
            self.rect.centerx = int(self.coord[0])
        if self.pressed[3]:
            self.coord[0] += cfg.HERO_SPEED
            if self.coord[0] > cfg.SCREEN_SIZE[0]:
                self.coord[0] = cfg.SCREEN_SIZE[0]
            self.rect.centerx = int(self.coord[0])
    # 绘制自己和血条
    def draw(self,screen):
        screen.blit(self.image,self.rect)
        pygame.draw.rect(screen, (0, 128, 0), (self.rect.x - 10, self.rect.y - 10, 70, 7))
        pygame.draw.rect(screen, (255, 0, 0), (self.rect.x - 10, self.rect.y - 10, 70 * (self.hp / cfg.MONSTERA_HP), 7 ))

# 针管
class Zhen(pygame.sprite.Sprite):
    # 根据英雄构建针管
    def __init__(self,hero,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.old_image = pygame.image.load(cfg.ZHEN_IMG_PATH).convert_alpha()
        self.old_image = pygame.transform.scale(self.old_image,cfg.ZHEN_IMG_SIZE)
        self.image = self.old_image
        self.rect = self.image.get_rect()
        self.hero = hero
        self.angle = 0
    # 更新自己位置，根据鼠标位置旋转
    def update(self,position):
        y = np.array([0,1])
        x = np.array([position[0] - self.hero.rect.centerx, -position[1] + self.hero.rect.centery])
        angle = tool.get_angel(x,y)
        self.angle = angle
        self.image = pygame.transform.rotate(self.old_image,angle)
        self.rect = self.image.get_rect()
        self.rect.center = self.hero.rect.center
    def draw(self,screen):
        screen.blit(self.image,self.rect)

# 英雄发射的普通炮弹
class Weapen0(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.WEAPEN_0_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.WEAPEN_0_SIZE)
        self.rect = self.image.get_rect()
        self.direction = [0.0,0.0]
        self.coord = [0.0,0.0]
        self.type = 0
    def set_direction(self,zhen):
        angle = tool.angle2pi(zhen.angle)
        self.direction = [-math.sin(angle),-math.cos(angle)]
        self.coord = [1.0*(zhen.rect.centerx + cfg.ZHEN_IMG_SIZE[0]/2 * self.direction[0]),1.0*(zhen.rect.centery + cfg.ZHEN_IMG_SIZE[1]/2 * self.direction[1])]
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    # 速度、更新位置、销毁、造成伤害
    def update(self):
        self.coord[0] += self.direction[0] * cfg.WEAPEN_0_SPEED
        self.coord[1] += self.direction[1] * cfg.WEAPEN_0_SPEED
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    def draw(self,screen):
        screen.blit(self.image,self.rect)

# 发射后的回旋镖
class Weapen1(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.old_image = pygame.image.load(cfg.WEAPEN_1_IMG_PATH).convert_alpha()
        self.old_image = pygame.transform.scale(self.old_image,cfg.WEAPEN_1_SIZE)
        self.image = self.old_image
        self.rect = self.image.get_rect()
        self.direction = [0.0,0.0]
        self.coord = [0.0,0.0]
        self.type = 1
        self.angle = 0
    def set_direction(self,zhen):
        angle = tool.angle2pi(zhen.angle)
        self.direction = [-math.sin(angle),-math.cos(angle)]
        self.coord = [1.0*(zhen.rect.centerx + cfg.ZHEN_IMG_SIZE[0]/2 * self.direction[0]),1.0*(zhen.rect.centery + cfg.ZHEN_IMG_SIZE[1]/2 * self.direction[1])]
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    def update(self):
        self.coord[0] += self.direction[0] * cfg.WEAPEN_1_SPEED
        self.coord[1] += self.direction[1] * cfg.WEAPEN_1_SPEED
        self.image = pygame.transform.rotate(self.old_image,self.angle)
        self.angle += cfg.WEAPEN_1_W
        self.rect = self.image.get_rect()
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    def draw(self,screen):
        screen.blit(self.image,self.rect)

# 随机出现后出现在地图上静止的等待hero去捡的回旋镖
class Weapen_1_static(pygame.sprite.Sprite):
    def __init__(self,position,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.WEAPEN_1_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.WEAPEN_1_SIZE)
        self.rect = self.image.get_rect()
        self.rect.centerx,self.rect.centery = position[0],position[1]
    def draw(self,screen):
        screen.blit(self.image,self.rect)

# 怪物A
class MonsterA(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.MONSTERA_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.MONSTERA_IMG_SIZE)
        self.rect = self.image.get_rect()
        self.attacted = False
        self.coord = [0.0,0.0]
        self.hp = cfg.MONSTERA_HP
        self.time = 0.0 # 攻击冷却计时器
        self.start_time = time.time()
    def set_position(self,position):
        self.rect.centerx,self.rect.centery = position[0],position[1]
        self.coord = [position[0]*1.0,position[1]*1.0]
    
    # 如何行动
    def act(self,hero):
        temp = hero.rect
        # 冷却计时
        self.time -= time.time()-self.start_time
        if self.time <= 0.0:
            self.time = 0.0
        self.start_time = time.time()
        vec = [temp.centerx - self.rect.centerx,temp.centery - self.rect.centery]
        dis = (vec[0]**2+vec[1]**2)**0.5
        # 距离不能为0，否则后面做除数会报错
        if dis == 0.0:
            dis = 0.01
        direction = [vec[0]/dis,vec[1]/dis]
        #print(self.rect)
        # 处于攻击范围内
        if dis <= cfg.MONSTERA_ATTACK_DIS or self.attacted:
            if pygame.sprite.collide_rect(self,hero):
                if self.time == 0.0:
                    # hero倒退 TODO!!!!! 暂时写成瞬移，后面改为有击退的过程
                    hero.rect.centerx += direction[0]*100
                    hero.rect.centery += direction[1]*100
                    # hero掉血
                    hero.hp -= cfg.MONSTERA_ATTACK_VALUE
                    self.time = cfg.MONSTERA_ATTACK_TIME
            else:
                self.coord[0] += direction[0]
                self.coord[1] += direction[1]
                self.rect.centerx = int(self.coord[0])
                self.rect.centery = int(self.coord[1])
        else: # wander
            # TODO!!!!!，在范围外时自由运动
            #print("wander")
            pass

    def be_hurt(self,weapen):
        self.attacted = True
        # 普通炮弹
        if weapen.type == 0:
            self.hp -= cfg.WEAPEN_0_VALUE
        # 强力回旋镖
        else:
            self.hp = 0

    def draw(self,screen):
        screen.blit(self.image,self.rect)
        pygame.draw.rect(screen, (0, 128, 0), (self.rect.x + 15, self.rect.y - 10, 70, 7))
        pygame.draw.rect(screen, (255, 0, 0), (self.rect.x + 15 ,self.rect.y - 10, 70 * (self.hp / cfg.MONSTERA_HP), 7 ))

# 怪物B
class MonsterB(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.old_image = pygame.image.load(cfg.MONSTERB_IMG_PATH).convert_alpha()
        self.old_image = pygame.transform.scale(self.old_image,cfg.MONSTERB_IMG_SIZE)
        self.image = self.old_image
        self.rect = self.image.get_rect()
        self.hp = cfg.MONSTERB_HP
        self.time = 0.0 # 攻击冷却计时器
        self.start_time = time.time()
    def set_position(self,position):
        self.rect.centerx,self.rect.centery = position[0],position[1]
    def be_hurt(self,weapen):
        self.attacted = True
        # 普通炮弹
        if weapen.type == 0:
            self.hp -= cfg.WEAPEN_0_VALUE
        # 强力回旋镖
        else:
            self.hp = 0
    # 如何行动
    def act(self,hero):
        temp = hero.rect
        # 冷却计时
        self.time -= time.time()-self.start_time
        if self.time <= 0.0:
            self.time = 0.0
        self.start_time = time.time()
        vec = [temp.centerx - self.rect.centerx,temp.centery - self.rect.centery]
        dis = (vec[0]**2+vec[1]**2)**0.5
        # 距离不能为0，否则后面做除数会报错
        if dis == 0.0:
            dis = 0.01
        direction = [vec[0]/dis,vec[1]/dis]
        # 转体
        y = np.array([0,1])
        x = np.array(direction)
        angle = -tool.get_angel(x,y)-45
        self.image = pygame.transform.rotate(self.old_image,angle)
        # ？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？？为啥不能写下面这行代码？？？？？
        # self.rect = self.image.get_rect()
        # 冷却到了之后，发射炮弹
        if self.time == 0.0:
            # 求position
            x = self.rect.centerx + cfg.MONSTERB_IMG_SIZE[0]/2*direction[0]
            y = self.rect.centery + cfg.MONSTERB_IMG_SIZE[1]/2*direction[1]
            pao = Pao(direction,(x,y)) # 构造炮弹
            self.time = cfg.MONSTERB_ATTACK_TIME
            return pao
        return 0

    def draw(self,screen):
        screen.blit(self.image,self.rect)
        pygame.draw.rect(screen, (0, 128, 0), (self.rect.x + 15, self.rect.y - 10, 70, 7))
        pygame.draw.rect(screen, (255, 0, 0), (self.rect.x + 15 ,self.rect.y - 10, 70 * (self.hp / cfg.MONSTERB_HP), 7 ))

# 怪物B发射的炮弹
class Pao(pygame.sprite.Sprite):
    def __init__(self,direction,position,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.PAO_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.PAO_IMG_SIZE)
        self.rect = self.image.get_rect()
        self.direction = direction
        self.coord = [1.0*position[0],1.0*position[1]]
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    # 速度、更新位置、销毁、造成伤害
    def update(self):
        self.coord[0] += self.direction[0] * cfg.PAO_SPEED
        self.coord[1] += self.direction[1] * cfg.PAO_SPEED
        self.rect.centerx = int(self.coord[0])
        self.rect.centery = int(self.coord[1])
    def draw(self,screen):
        screen.blit(self.image,self.rect)
    
# 第三关的Boss，喷射小怪
class Boss(pygame.sprite.Sprite):
    def __init__(self,**kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.BOSS_IMG_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.BOSS_IMG_SIZE)
        self.rect = self.image.get_rect()
        self.hp = cfg.BOSS_HP
        self.time_max = cfg.BOSS_ATTACK_TIME
        self.time = 0.0 # 攻击冷却计时器
        self.start_time = time.time()
        self.locs = cfg.BOSS_LOCS
        self.red = False
    def set_position(self,position):
        self.rect.centerx,self.rect.centery = position[0],position[1]
    def be_hurt(self,weapen):
        self.attacted = True
        # 普通炮弹
        if weapen.type == 0:
            self.hp -= cfg.WEAPEN_0_VALUE
        # 强力回旋镖
        else:
            self.hp = self.hp//2
    # 红血状态后，boss行为改变：颜色改变、发射小怪频率提高
    def red_blood(self):
        self.image = pygame.image.load(cfg.BOSS_IMG_RED_PATH).convert_alpha()
        self.image = pygame.transform.scale(self.image,cfg.BOSS_IMG_SIZE)
        self.time_max = cfg.BOSS_ATTACK_TIME_RED
        self.red = True
    # 如何行动,将小怪添加到live里去
    def act(self,mons_live):
        # 冷却计时
        self.time -= time.time()-self.start_time
        if self.time <= 0.0:
            self.time = 0.0
        self.start_time = time.time()
        # 冷却到了之后，发射MonsterA
        if self.time == 0.0:
            for loc in self.locs:
                x = loc[0] + self.rect.centerx
                y = loc[1] + self.rect.centery
                ma = MonsterA()
                ma.set_position((x,y))
                ma.attacted = True
                mons_live.add(ma)
            self.time = self.time_max
    def draw(self,screen):
        screen.blit(self.image,self.rect)
        pygame.draw.rect(screen, (0, 128, 0), (self.rect.x + 15, self.rect.y - 20, 150, 7))
        pygame.draw.rect(screen, (255, 0, 0), (self.rect.x + 15 ,self.rect.y - 20, 150 * (self.hp / cfg.BOSS_HP), 7 ))
    
    